package com.cn.thread.condition;


import com.cn.thread.common.BufferResources;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionBufferResources implements BufferResources {

    private int maxSize = 10;
    //这里用list作为缓冲区，也可以替换为队列
    private LinkedList list = new LinkedList<Integer>();
    //创建锁
    private Lock lock = new ReentrantLock();
    //生产者对应Condition
    private Condition producerCondition = lock.newCondition();
    //消费者对应Condition
    private Condition consumerCondition = lock.newCondition();


    public void consume() {
        lock.lock();
        try{
            while (list.size() == 0) {
                System.out.println(Thread.currentThread().getName() + " 当前缓冲区为空，等待生产中...");
                try {
                    //消费者进入等待状态
                    consumerCondition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //进行消费数据，从First开始消费，模拟队列
            Integer value = (Integer) list.removeFirst();
            System.out.println(Thread.currentThread().getName() + " 消费成功：" + value.toString() + " 当前缓冲区size = " + list.size());
            //消费完毕后，只唤醒生产者
            producerCondition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //一定要用finally执行解锁
            lock.unlock();
        }
    }

    public void product(Integer value){
        lock.lock();
        try{
            while (list.size() == maxSize) {
                System.out.println(Thread.currentThread().getName() + " 当前缓冲区满了，等待消费中...");
                //生产者进入等待状态
                producerCondition.await();
            }
            //进生产数据
            list.add(value);
            System.out.println(Thread.currentThread().getName() + " 生产成功：" + value.toString() + " 当前缓冲区size = " + list.size());
            //生产完毕后，只唤醒消费者
            consumerCondition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //一定要用finally执行解锁
            lock.unlock();
        }
    }
}
